package jrandom.wizards;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class JRandomTestCaseWizardPage3 extends WizardPage {
	
	private JRandomTestCaseWizardPage2 jPage2;
	
	private Composite composite;
	private GridLayout layout;
	
	private Text methodText;
	private IMethod method;
	private String[] paraTypes;
	private String[] paraNames;
	private Text[] minText;
	private Text[] maxText;
	
	public JRandomTestCaseWizardPage3(JRandomTestCaseWizardPage2 page2) {
		super("wizardPage3");
		setTitle("Parameter's Domain Set");
		setDescription("Set input domain for each parameter of selected method.");
		setPageComplete(false);
		this.jPage2 = page2;
	}

	@Override
	public void createControl(Composite parent) {
		composite = new Composite(parent, SWT.NULL);
		layout = new GridLayout();
		layout.numColumns = 2;
		layout.verticalSpacing = 15;
		composite.setLayout(layout);
		
		createMethodControls(composite, layout.numColumns);
		
		// very important code below
		setControl(composite);
	}

	public void setVisible(boolean visible) {
		super.setVisible(visible);
		if (visible) {
			method = jPage2.getCheckedMethods()[0];
			try {
				String modifier = Flags.toString(method.getFlags());
				String signature = method.getSignature();
				String name = method.getElementName();
				paraTypes = method.getParameterTypes();
				paraNames = method.getParameterNames();
				methodText.setText(modifier + " " + Signature.toString(signature, name, paraNames, false, !method.isConstructor()) 
						+ " ---- " + method.getDeclaringType().getFullyQualifiedName('$'));
				
				minText = new Text[paraTypes.length];
				maxText = new Text[paraTypes.length];
				Control[] controls = composite.getChildren();
				for (int i = 2; i < controls.length; i++) {
					controls[i].dispose();
				}
				for (int i = 0; i < paraTypes.length; i++) {
					createDomainControls(composite, layout.numColumns, i);
				}
				composite.layout(true);
				setPageComplete(true);
			} catch (JavaModelException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			setPageComplete(false);
		}
	}

	private void createMethodControls(Composite parent, int numColumns) {
		Label label = new Label(parent, SWT.NONE);
		label.setText("Method: ");
		methodText = new Text(parent, SWT.BORDER | SWT.SINGLE);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalSpan = numColumns - 1;
		methodText.setLayoutData(gridData);
		methodText.setEditable(false);
	}

	private void createDomainControls(Composite parent, int numColumns, int i) {
		Group group = new Group(parent, SWT.NONE);
		group.setText(Signature.toString(paraTypes[i]) + " " + paraNames[i]);
		GridData gridData = new GridData();
		gridData.horizontalAlignment = GridData.FILL;
		gridData.horizontalSpan = numColumns;
		group.setLayoutData(gridData);
		GridLayout gridLayout = new GridLayout(4, false);
		group.setLayout(gridLayout);
		
		Label min = new Label(group, SWT.NONE);
		min.setText("Min Value: ");
		minText[i] = new Text(group, SWT.BORDER | SWT.SINGLE);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalSpan = 1;
		minText[i].setLayoutData(gridData);
		
		Label max = new Label(group, SWT.NONE);
		max.setText("Max Value: ");
		maxText[i] = new Text(group, SWT.BORDER | SWT.SINGLE);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalSpan = 1;
		maxText[i].setLayoutData(gridData);
		
		if (paraTypes[i].equals(Signature.SIG_INT)) {
			minText[i].setText(Integer.toString(Integer.MIN_VALUE));
			maxText[i].setText(Integer.toString(Integer.MAX_VALUE));
		} else if (paraTypes[i].equals(Signature.SIG_CHAR)) {
			minText[i].setText(Character.toString(Character.MIN_VALUE));
			maxText[i].setText(Character.toString(Character.MAX_VALUE));
		} else if (paraTypes[i].equals(Signature.SIG_DOUBLE)) {
			minText[i].setText(Double.toString(Double.MIN_VALUE));
			maxText[i].setText(Double.toString(Double.MAX_VALUE));
		} else if (Signature.toString(paraTypes[i]).equals("String")) {
			minText[i].setText("a");
			maxText[i].setText("helloWorld");
		} else {
			minText[i].setEnabled(false);
			maxText[i].setEnabled(false);
		}
	}

	public IMethod getMethod() {
		return method;
	}

	public String[] getParaTypes() {
		return paraTypes;
	}

	public String[] getParaNames() {
		return paraNames;
	}

	public String[] getMinValues() {
		String[] mins = new String[minText.length];
		for (int i = 0; i < minText.length; i++) {
			mins[i] = minText[i].getText();
		}
		return mins;
	}

	public String[] getMaxValues() {
		String[] maxs = new String[maxText.length];
		for (int i = 0; i < maxText.length; i++) {
			maxs[i] = maxText[i].getText();
		}
		return maxs;
	}

}
